#ifndef TERRAIN_H
#define TERRAIN_H

#include "parcelle.hpp"
#include "lecteur.hpp"
#include <cstdlib>
#include <vector>

using namespace std;

struct bassin_t
{
    unsigned int id;
    Parcelle puit;
};

struct parchaine
{
    Parcelle * parc;
    parchaine * maillon;
};


class Terrain
{
private :
    unsigned int nbBassin;//nombre de bassin déja attribué"
    vector<bassin_t>* lesBassins;
    Parcelle* lesParcelles_up;
    Parcelle* lesParcelles_center;
    Parcelle* lesParcelles_down;
    Parcelle* lesParcelles_downdown;
    int* ligneCourante;
    int* ecriture;
    unsigned int lignes_traitees;
    FileManager * lecteur;
    int jucpt;

    map<int,int> MAJBassin;

public:
    Terrain()
    {
        this->nbBassin = 0;
        this->lesBassins = new vector<bassin_t>();

        //this-> ligneCourante = new vector<unsigned int>();
        this->lecteur = NULL;
        this->lignes_traitees = 0;
        jucpt = 1;
    }

    ~Terrain()
    {
        if (lesBassins)
        {
            lesBassins->clear();
            delete lesBassins;
        }
        if(lesParcelles_up)
        {
            delete lesParcelles_up;
        }
        if (lesParcelles_center)
        {
            delete lesParcelles_center;
        }
        if (lesParcelles_down)
        {
            delete lesParcelles_down;
        }
        if (ligneCourante)
        {
            //ligneCourante->clear();
            delete ligneCourante;
        }

    }

    unsigned int getNbBassin()
    {
        return nbBassin;
    };
    vector<bassin_t>* getLesBassins()
    {
        return lesBassins;
    }
    Parcelle* getP_UP()
    {
        return lesParcelles_up;
    }
    Parcelle* getP_CENTER()
    {
        return lesParcelles_center;
    }
    Parcelle* getP_DOWN()
    {
        return lesParcelles_down;
    }
    Parcelle* getParcelle(unsigned int x, unsigned int y)
    {
        ////////////////////////////

        if(lesParcelles_up != NULL && lesParcelles_up[x].getOrd() == y)
        {
            return &lesParcelles_up[x];
        }
        if(lesParcelles_center != NULL && lesParcelles_center[x].getOrd() == y)
        {
            return &lesParcelles_center[x];
        }
        if(lesParcelles_down != NULL && lesParcelles_down[x].getOrd() == y)
        {
            return &lesParcelles_down[x];
        }
        if(lesParcelles_downdown != NULL && lesParcelles_downdown[x].getOrd() == y)
        {
            return &lesParcelles_downdown[x];
        }
        /////////
        /*std::cout<<x<<" "<<y<<endl;;
        if (lesParcelles_up != NULL)
        {

            for(unsigned int i =0; i<lecteur->getNbCol(); i++)
            {
                if (lesParcelles_up[i].getAbs() == x && lesParcelles_up[i].getOrd() ==y)
                {
                   // lesParcelles_up[i].affiche();
                    return &lesParcelles_up[i];
                }
            }
        }
        if(lesParcelles_center != NULL)
        {
            for(unsigned int j =0; j<lecteur->getNbCol(); j++)
            {
                if (lesParcelles_center[j].getAbs() == x && lesParcelles_center[j].getOrd() ==y)
                {
                   // lesParcelles_center[j].affiche();
                    return &lesParcelles_center[j];
                }
            }
        }
        if(lesParcelles_down != NULL)
        {

            for(unsigned int l=0; l<lecteur->getNbCol(); l++)
            {
                if(lesParcelles_down[l].getAbs() == x && lesParcelles_down[l].getOrd() == y)
                {
                    //lesParcelles_down[l].affiche();
                    return &lesParcelles_down[l];
                }
            }
        }
        if(lesParcelles_downdown != NULL){
         for(unsigned int z=0; z<lecteur->getNbCol(); z++)
            {
                if(lesParcelles_downdown[z].getAbs() == x && lesParcelles_downdown[z].getOrd() == y)
                {
                    //lesParcelles_down[l].affiche();
                    return &lesParcelles_downdown[z];
                }
            }
        }*/
        return NULL;
    }



    FileManager* getLecteur()
    {
        return lecteur;
    }
    void setLecteur(FileManager* f)
    {
        lecteur= f;
    }

    void calcul();

    void setNbBassin(unsigned int i)
    {
        nbBassin = i;
    }
    // void setLesParcelles(vector<Parcelle*>* v){
    Parcelle* calculCible(Parcelle *p);
    void calculCuvette(Parcelle *p);


    void afficheLesBassins();
    void calculRegroupBassin();
    // }
};

inline Parcelle* Terrain::calculCible(Parcelle *p)
{
    Box::cpt++;
    if( p->getHauteur() == lecteur->getNoValue())
    {
        return p;
    }

    // p->affiche();
    Parcelle *res = new Parcelle(INT_MAX,0,0);
    Parcelle* current = NULL;
    unsigned int abs, ord, nbcol;
    int noval = lecteur->getNoValue(), hauteur = res->getHauteur();
    abs=p->getAbs();ord=p->getOrd();nbcol=lecteur->getNbCol();

    // GARE AUX BORDS

    //si collee au bas
    if(ord < lignes_traitees-1)
    {
        // bas droite
        if ( abs <nbcol-1)
        {
            current=getParcelle(abs+1, ord+1);
            if(current->getHauteur() < hauteur && current->getHauteur() != noval)
            {
                res = current;
                hauteur = res->getHauteur();
            }
        }
        // bas
        current=getParcelle(abs, ord+1);
        if(current->getHauteur() < hauteur && current->getHauteur() != noval)
        {
            res = current;
            hauteur = res->getHauteur();
        }

    // bas gauche
        if (abs >=1)
        {
            current=getParcelle(abs-1, ord+1);
            if(current->getHauteur() < hauteur && current->getHauteur() != noval)
            {
                res = current;
                hauteur = res->getHauteur();
            }
        }
    }
// droite
    if (abs < nbcol-1)
    {
        current=getParcelle(abs+1, ord);
        if(current->getHauteur() <= hauteur && current->getHauteur() != noval)
        {
            res = current;
            hauteur = res->getHauteur();
        }
    }
    //centre
    current=getParcelle(abs,ord);
    if(current->getHauteur() <= hauteur && current->getHauteur() != noval)
    {
        res = p;
        hauteur = res->getHauteur();
    }
    // gauche
    if (abs >= 1)
    {
        current=getParcelle(abs-1, ord);
        if(current->getHauteur() <= hauteur && current->getHauteur() != noval)
        {
            res = current;
            hauteur = res->getHauteur();
        }
    }
    //si haut
    if(ord >lignes_traitees-4)
    {
        // haut droite
        if (abs < nbcol-1)
        {
            current=getParcelle(abs+1, ord-1);
            if(current->getHauteur() <= hauteur && current->getHauteur() != noval)
            {
                res = current;
                hauteur = res->getHauteur();
            }
        }
        // haut
        current=getParcelle(abs, ord-1);
        if(current->getHauteur() <= hauteur && current->getHauteur() != noval)
        {
            res = current;
            hauteur = res->getHauteur();
        }

        // haut gauche
        if (abs >=1)
        {
            current=getParcelle((abs)-1, (ord)-1);
            if(current->getHauteur() <= hauteur && current->getHauteur() != noval)
            {
                res = current;
                hauteur = res->getHauteur();
            }
        }
    }

    return res;

}



#endif
